package com.geek.bams.dao;

import com.geek.bams.entity.Account;

import java.io.*;
import java.util.*;


public class FileDao implements IDao<Account , List<Account>>{
    // 文件路径常量
    //private static final String ACCOUNTS_FILE = "BAMS\\personInfo\\accounts.txt";
    
    // 单独账户文件的目录
    private static final String ACCOUNTS_DIR = "BAMS\\personInfo\\accounts\\";

    // ID 文件路径常量
    private static final String ID_FILE = "BAMS\\personInfo\\nextId.txt";
    
    // 默认起始 ID
    private static final Long DEFAULT_ID = 862150212025100001L;
    
    @Override
    public Long getId() {
        return readNextIdFromFile();
    }

    @Override
    public void setId(Long id) {
        saveNextIdToFile(id);
    }

    /**
     * 从文件读取下一个可用的 ID
     */
    private Long readNextIdFromFile() {
        File file = new File(ID_FILE);
        if (!file.exists()) {
            // 文件不存在时，创建并写入默认 ID
            saveNextIdToFile(DEFAULT_ID);
            return DEFAULT_ID;
        }
        
        try (BufferedReader reader = new BufferedReader(new FileReader(file))) {
            String idStr = reader.readLine();
            //trim  去除空格
            if (idStr != null && !idStr.trim().isEmpty()) {
                return Long.valueOf(idStr.trim());
            }
        } catch (IOException | NumberFormatException e) {
            System.err.println("读取 ID 文件出错: " + e.getMessage());
        }
        
        // 如果读取失败，返回默认 ID
        return DEFAULT_ID;
    }
    
    /**
     * 将下一个可用的 ID 保存到文件
     */
    private void saveNextIdToFile(Long id) {
        File file = new File(ID_FILE);
        try {
            // 确保目录存在
            file.getParentFile().mkdirs();
            try (BufferedWriter writer = new BufferedWriter(new FileWriter(file))) {
                writer.write(id.toString());
            }
        } catch (IOException e) {
            System.err.println("保存 ID 文件出错: " + e.getMessage());
        }
    }

    @Override
    public boolean insert(Account account) throws IOException {
        // 为新账户创建单独的文件
        return saveAccountToIndividualFile(account);
    }

    @Override
    public boolean update(Account account) throws IOException {
        // 直接更新对应的单独文件
        return saveAccountToIndividualFile(account);
    }

    @Override
    public Account selectOne(Long id, String password) throws IOException, ClassNotFoundException {
        // 直接从单独文件读取账户
        Account account = loadAccountFromIndividualFile(id);
        if (account != null && account.getPassword().equals(password)) {
            return account;
        }
        return null;
    }

    @Override
    public Account selectOne(Long id) {
        try {
            // 直接从单独文件读取账户
            return loadAccountFromIndividualFile(id);
        } catch (Exception e) {
            System.err.println("查询单个账户出错: " + e.getMessage());
        }
        return null;
    }

    @Override
    public List<Account> selectAll() {
        List<Account> accounts = new ArrayList<>();
        File accountsDir = new File(ACCOUNTS_DIR);
        
        // 如果目录不存在，返回空列表
        if (!accountsDir.exists() || !accountsDir.isDirectory()) {
            return accounts;
        }
        
        // 遍历目录中的所有.txt文件
        File[] files = accountsDir.listFiles((dir, name) -> name.endsWith(".txt"));
        if (files != null) {
            for (File file : files) {
                try {
                    // 从文件名获取账户ID
                    String fileName = file.getName();
                    String idStr = fileName.substring(0, fileName.length() - 4); // 去掉.txt
                    Long id = Long.valueOf(idStr);
                    
                    // 加载账户信息
                    Account account = loadAccountFromIndividualFile(id);
                    if (account != null) {
                        accounts.add(account);
                    }
                } catch (Exception e) {
                    System.err.println("读取账户文件出错: " + file.getName() + " - " + e.getMessage());
                }
            }
        }
        
        return accounts;
    }

    @Override
    public Long createID() throws IOException {
        // 读取文件中的下一个可用 ID（这就是要分配给新账户的ID）
        Long idToAssign = readNextIdFromFile();
        
        // 如果是第一次使用（文件中是默认值），初始化为当前年月格式
        if (idToAssign.equals(DEFAULT_ID)) {
            Calendar c = Calendar.getInstance();
            int year = c.get(Calendar.YEAR);
            int month = c.get(Calendar.MONTH) + 1;
            String monthStr = month < 10 ? "0" + month : String.valueOf(month);
            idToAssign = Long.valueOf("86215021" + year + monthStr + "0001");
        }
        
        // 检查月份是否需要重置
        String idStr = idToAssign.toString();
        if (idStr.length() >= 18) {
            Integer year = Integer.valueOf(idStr.substring(8, 12));
            Integer month = Integer.valueOf(idStr.substring(12, 14));
            Integer count = Integer.valueOf(idStr.substring(14));
            
            Calendar c = Calendar.getInstance();
            int nowYear = c.get(Calendar.YEAR);
            int nowMonth = c.get(Calendar.MONTH) + 1;
            
            if (!year.equals(nowYear) || !month.equals(nowMonth)) {
                // 新的年月，重置计数到0001
                String monthStr = nowMonth < 10 ? "0" + nowMonth : String.valueOf(nowMonth);
                idToAssign = Long.valueOf("86215021" + nowYear + monthStr + "0001");
            }
            
            // 检查是否达到上限
            if (count >= 9999) {
                System.out.println("本月已满，下月再来");
                return -1L;
            }
        }
        
        // 计算下一个 ID 并保存到文件（为下次分配准备）
        Long nextId = generateNextId(idToAssign);
        saveNextIdToFile(nextId);
        
        // 返回当前要分配的 ID
        return idToAssign;
    }
    
    /**
     * 生成下一个 ID
     */
    private Long generateNextId(Long currentId) {
        String idStr = currentId.toString();
        if (idStr.length() >= 18) {
            Integer count = Integer.valueOf(idStr.substring(14));
            // 生成下一个计数
            String nextCountStr = String.format("%04d", count + 1);
            return Long.valueOf(idStr.substring(0, 14) + nextCountStr);
        }
        return currentId + 1;
    }
    
    /**
     * 获取单个账户文件的路径
     * @param id 账户ID
     * @return 文件路径
     */
    private String getIndividualAccountFilePath(Long id) {
        return ACCOUNTS_DIR + id + ".txt";
    }
    
    /**
     * 将单个账户保存到独立文件
     * @param account 账户对象
     * @return 是否保存成功
     */
    private boolean saveAccountToIndividualFile(Account account) throws IOException {
        String filePath = getIndividualAccountFilePath(account.getId());
        File file = new File(filePath);
        
        // 确保目录存在
        file.getParentFile().mkdirs();
        
        try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(file))) {
            oos.writeObject(account);
            System.out.println("账户信息已保存到文件: " + filePath);
            return true;
        } catch (IOException e) {
            System.err.println("保存账户文件出错: " + e.getMessage());
            throw e;
        }
    }
    
    /**
     * 从独立文件加载账户信息
     * @param id 账户ID
     * @return 账户对象，如果文件不存在或读取失败则返回null
     */
    private Account loadAccountFromIndividualFile(Long id) {
        String filePath = getIndividualAccountFilePath(id);
        File file = new File(filePath);
        
        if (!file.exists() || file.length() == 0) {
            return null;
        }
        
        try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(file))) {
            return (Account) ois.readObject();
        } catch (IOException | ClassNotFoundException e) {
            System.err.println("读取账户文件出错: " + filePath + " - " + e.getMessage());
            return null;
        }
    }
}
